home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -screenplay- / shareware / warpquake / warpquakesrc / r_aliasa.s < prev    next >
Text File  |  2000-02-29  |  7KB  |  238 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. //
  21. // r_aliasa.s
  22. // x86 assembly-language Alias model transform and project code.
  23. //
  24.  
  25. #include "asm_i386.h"
  26. #include "quakeasm.h"
  27. #include "asm_draw.h"
  28. #include "d_ifacea.h"
  29.  
  30. #if id386
  31.  
  32.     .data
  33.  
  34. Lfloat_1:    .single    1.0
  35. Ltemp:        .long    0
  36. Lcoords:    .long    0, 0, 0
  37.  
  38.     .text
  39.  
  40. #define fv            12+4
  41. #define pstverts    12+8
  42.  
  43. .globl C(R_AliasTransformAndProjectFinalVerts)
  44. C(R_AliasTransformAndProjectFinalVerts):
  45.     pushl    %ebp                // preserve caller's stack frame
  46.     pushl    %edi
  47.     pushl    %esi                // preserve register variables
  48.  
  49. //    int            i, temp;
  50. //    float        lightcos, *plightnormal, zi;
  51. //    trivertx_t    *pverts;
  52.  
  53. //    pverts = r_apverts;
  54.     movl    C(r_apverts),%esi
  55.  
  56. //    for (i=0 ; i<r_anumverts ; i++, fv++, pverts++, pstverts++)
  57. //    {
  58.     movl    pstverts(%esp),%ebp
  59.     movl    fv(%esp),%edi
  60.     movl    C(r_anumverts),%ecx
  61.     subl    %edx,%edx
  62.  
  63. Lloop:
  64.  
  65. //    // transform and project
  66. //        zi = 1.0 / (DotProduct(pverts->v, aliastransform[2]) +
  67. //                aliastransform[2][3]);
  68.     movb    (%esi),%dl
  69.     movb    %dl,Lcoords
  70.     fildl    Lcoords                // v[0]
  71.     movb    1(%esi),%dl
  72.     movb    %dl,Lcoords+4
  73.     fildl    Lcoords+4            // v[1] | v[0]
  74.     movb    2(%esi),%dl    
  75.     movb    %dl,Lcoords+8
  76.     fildl    Lcoords+8            // v[2] | v[1] | v[0]
  77.  
  78.     fld        %st(2)                // v[0] | v[2] | v[1] | v[0]
  79.     fmuls    C(aliastransform)+32 // accum | v[2] | v[1] | v[0]
  80.     fld        %st(2)                // v[1] | accum | v[2] | v[1] | v[0]
  81.     fmuls    C(aliastransform)+36 // accum2 | accum | v[2] | v[1] | v[0]
  82.     fxch    %st(1)                // accum | accum2 | v[2] | v[1] | v[0]
  83.     fadds    C(aliastransform)+44 // accum | accum2 | v[2] | v[1] | v[0]
  84.     fld        %st(2)                // v[2] | accum | accum2 | v[2] | v[1] | v[0]
  85.     fmuls    C(aliastransform)+40 // accum3 | accum | accum2 | v[2] | v[1] |
  86.                                  //  v[0]
  87.     fxch    %st(1)                // accum | accum3 | accum2 | v[2] | v[1] | v[0]
  88.     faddp    %st(0),%st(2)        // accum3 | accum | v[2] | v[1] | v[0]
  89.     movb    tv_lightnormalindex(%esi),%dl
  90.     movl    stv_s(%ebp),%eax
  91.     movl    %eax,fv_v+8(%edi)
  92.     faddp    %st(0),%st(1)        // z | v[2] | v[1] | v[0]
  93.  
  94.     movl    stv_t(%ebp),%eax
  95.     movl    %eax,fv_v+12(%edi)
  96.  
  97. //    // lighting
  98. //        plightnormal = r_avertexnormals[pverts->lightnormalindex];
  99.  
  100.     fdivrs    Lfloat_1            // zi | v[2] | v[1] | v[0]
  101.  
  102. //        fv->v[2] = pstverts->s;
  103. //        fv->v[3] = pstverts->t;
  104. //        fv->flags = pstverts->onseam;
  105.     movl    stv_onseam(%ebp),%eax
  106.     movl    %eax,fv_flags(%edi)
  107.  
  108.     movl    fv_size(%edi),%eax
  109.     movl    stv_size(%ebp),%eax
  110.     movl    4(%esi),%eax
  111.  
  112.     leal    (%edx,%edx,2),%eax    // index*3
  113.  
  114.     fxch    %st(3)                // v[0] | v[2] | v[1] | zi
  115.  
  116. //        lightcos = DotProduct (plightnormal, r_plightvec);
  117.     flds    C(r_avertexnormals)(,%eax,4)
  118.     fmuls    C(r_plightvec)
  119.     flds    C(r_avertexnormals)+4(,%eax,4)
  120.     fmuls    C(r_plightvec)+4
  121.     flds    C(r_avertexnormals)+8(,%eax,4)
  122.     fmuls    C(r_plightvec)+8
  123.     fxch    %st(1)
  124.     faddp    %st(0),%st(2)
  125.     fld        %st(2)                 // v[0] | laccum | laccum2 | v[0] | v[2] |
  126.                                  //  v[1] | zi
  127.     fmuls    C(aliastransform)+0  // xaccum | laccum | laccum2 | v[0] | v[2] |
  128.                                  //  v[1] | zi
  129.     fxch    %st(2)                 // laccum2 | laccum | xaccum | v[0] | v[2] |
  130.                                  //  v[1] | zi
  131.     faddp    %st(0),%st(1)         // laccum | xaccum | v[0] | v[2] | v[1] | zi
  132.  
  133. //        temp = r_ambientlight;
  134. //        if (lightcos < 0)
  135. //        {
  136.     fsts    Ltemp
  137.     movl    C(r_ambientlight),%eax
  138.     movb    Ltemp+3,%dl
  139.     testb    $0x80,%dl
  140.     jz        Lsavelight    // no need to clamp if only ambient lit, because
  141.                         //  r_ambientlight is preclamped
  142.  
  143. //            temp += (int)(r_shadelight * lightcos);
  144.     fmuls    C(r_shadelight)
  145. // FIXME: fast float->int conversion?
  146.     fistpl    Ltemp
  147.     addl    Ltemp,%eax
  148.  
  149. //        // clamp; because we limited the minimum ambient and shading light, we
  150. //        // don't have to clamp low light, just bright
  151. //            if (temp < 0)
  152. //                temp = 0;
  153.     jns        Lp1
  154.     subl    %eax,%eax
  155.  
  156. //        }
  157.  
  158. Lp1:
  159.  
  160. //        fv->v[4] = temp;
  161. //
  162. //    // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
  163. //    // scaled up by 1/2**31, and the scaling cancels out for x and y in the
  164. //    // projection
  165. //        fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) +
  166. //                aliastransform[0][3]) * zi) + aliasxcenter;
  167. //        fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) +
  168. //                aliastransform[1][3]) * zi) + aliasycenter;
  169. //        fv->v[5] = zi;
  170.     fxch    %st(1)                 // v[0] | xaccum | v[2] | v[1] | zi
  171.     fmuls    C(aliastransform)+16 // yaccum | xaccum | v[2] | v[1] | zi
  172.     fxch    %st(3)                 // v[1] | xaccum | v[2] | yaccum | zi
  173.     fld        %st(0)                 // v[1] | v[1] | xaccum | v[2] | yaccum | zi
  174.     fmuls    C(aliastransform)+4     // xaccum2 | v[1] | xaccum | v[2] | yaccum |zi
  175.     fxch    %st(1)                 // v[1] | xaccum2 | xaccum | v[2] | yaccum |zi
  176.     movl    %eax,fv_v+16(%edi)
  177.     fmuls    C(aliastransform)+20 // yaccum2 | xaccum2 | xaccum | v[2] | yaccum|
  178.                                  //  zi
  179.     fxch    %st(2)                 // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
  180.                                  //  zi
  181.     fadds    C(aliastransform)+12 // xaccum | xaccum2 | yaccum2 | v[2] | yaccum|
  182.                                  //  zi
  183.     fxch    %st(4)                 // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
  184.                                  //  zi
  185.     fadds    C(aliastransform)+28 // yaccum | xaccum2 | yaccum2 | v[2] | xaccum|
  186.                                  //  zi
  187.     fxch    %st(3)                 // v[2] | xaccum2 | yaccum2 | yaccum | xaccum|
  188.                                  //  zi
  189.     fld        %st(0)                 // v[2] | v[2] | xaccum2 | yaccum2 | yaccum |
  190.                                  //  xaccum | zi
  191.     fmuls    C(aliastransform)+8     // xaccum3 | v[2] | xaccum2 | yaccum2 |yaccum|
  192.                                  //  xaccum | zi
  193.     fxch    %st(1)                 // v[2] | xaccum3 | xaccum2 | yaccum2 |yaccum|
  194.                                  //  xaccum | zi
  195.     fmuls    C(aliastransform)+24 // yaccum3 | xaccum3 | xaccum2 | yaccum2 |
  196.                                  // yaccum | xaccum | zi
  197.     fxch    %st(5)                 // xaccum | xaccum3 | xaccum2 | yaccum2 |
  198.                                  // yaccum | yaccum3 | zi
  199.     faddp    %st(0),%st(2)         // xaccum3 | xaccum | yaccum2 | yaccum |
  200.                                  //  yaccum3 | zi
  201.     fxch    %st(3)                 // yaccum | xaccum | yaccum2 | xaccum3 |
  202.                                  //  yaccum3 | zi
  203.     faddp    %st(0),%st(2)         // xaccum | yaccum | xaccum3 | yaccum3 | zi
  204.     addl    $(tv_size),%esi
  205.     faddp    %st(0),%st(2)         // yaccum | x | yaccum3 | zi
  206.     faddp    %st(0),%st(2)         // x | y | zi
  207.     addl    $(stv_size),%ebp
  208.     fmul    %st(2),%st(0)         // x/z | y | zi
  209.     fxch    %st(1)                 // y | x/z | zi
  210.     fmul    %st(2),%st(0)         // y/z | x/z | zi
  211.     fxch    %st(1)                 // x/z | y/z | zi
  212.     fadds    C(aliasxcenter)         // u | y/z | zi
  213.     fxch    %st(1)                 // y/z | u | zi
  214.     fadds    C(aliasycenter)         // v | u | zi
  215.     fxch    %st(2)                 // zi | u | v
  216. // FIXME: fast float->int conversion?
  217.     fistpl    fv_v+20(%edi)         // u | v
  218.     fistpl    fv_v+0(%edi)         // v
  219.     fistpl    fv_v+4(%edi)
  220.  
  221. //    }
  222.  
  223.     addl    $(fv_size),%edi
  224.     decl    %ecx
  225.     jnz        Lloop
  226.  
  227.     popl    %esi                // restore register variables
  228.     popl    %edi
  229.     popl    %ebp                // restore the caller's stack frame
  230.     ret
  231.  
  232. Lsavelight:
  233.     fstp    %st(0)
  234.     jmp        Lp1
  235.  
  236. #endif    // id386
  237.  
  238.